package com.xxl.job.admin.controller.weds;

import com.xxl.job.admin.controller.annotation.BizLimit;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dto.JsonData;
import com.xxl.job.admin.dto.NextTriggerTimeDto;
import com.xxl.job.admin.dto.TaskDto;
import com.xxl.job.admin.dto.TriggerDto;
import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description 任务接口
 * @Author lihw
 * @Date 2024/1/17 9:53
 */
@Slf4j
@RestController
@RequestMapping("/weds/task/v1")
public class TaskController {
    @Resource
    private XxlJobGroupDao xxlJobGroupDao;
    @Resource
    private XxlJobService xxlJobService;

    @BizLimit
    @PermissionLimit(limit = false)
    @PostMapping("/pageList")
    public JsonData pageList(@RequestBody TaskDto taskDto) {

        return JsonData.buildSuccess(xxlJobService.pageList(taskDto.getStart(), taskDto.getLength(), taskDto.getJobGroup(),
                taskDto.getTriggerStatus(), taskDto.getJobDesc(), taskDto.getExecutorHandler(), taskDto.getAuthor()));
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @PostMapping("/add")
    public JsonData add(@RequestBody XxlJobInfo jobInfo) {

        return JsonData.buildFromReturnT(xxlJobService.add(setDefaultProperty(jobInfo)));
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @PostMapping("/update")
    public JsonData update(@RequestBody XxlJobInfo jobInfo) {
        return JsonData.buildFromReturnT(xxlJobService.update(setDefaultProperty(jobInfo)));
    }

    /**
     * 设置默认属性
     * @param jobInfo
     * @return
     */
    public XxlJobInfo setDefaultProperty(XxlJobInfo jobInfo) {
        if (StringUtils.isBlank(jobInfo.getScheduleType())) {
            jobInfo.setScheduleType("CRON");
        }
        if (StringUtils.isBlank(jobInfo.getMisfireStrategy())) {
            jobInfo.setMisfireStrategy("DO_NOTHING");
        }
        if (StringUtils.isBlank(jobInfo.getExecutorRouteStrategy())) {
            jobInfo.setExecutorRouteStrategy("FIRST");
        }
        if (StringUtils.isBlank(jobInfo.getExecutorBlockStrategy())) {
            jobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        }

        return jobInfo;
    }


    @BizLimit
    @PermissionLimit(limit = false)
    @GetMapping("/remove")
    public JsonData remove(int id) {
        return JsonData.buildFromReturnT(xxlJobService.remove(id));
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @GetMapping("/stop")
    public JsonData pause(int id) {
        return JsonData.buildFromReturnT(xxlJobService.stop(id));
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @GetMapping("/start")
    public JsonData start(int id) {
        return JsonData.buildFromReturnT(xxlJobService.start(id));
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @PostMapping("/trigger")
    public JsonData triggerJob(@RequestBody TriggerDto triggerDto) {

        Integer id = triggerDto.getId();
        String executorParam = triggerDto.getExecutorParam();
        String addressList = triggerDto.getAddressList();
        // force cover job param
        if (executorParam == null) {
            executorParam = "";
        }

        JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
        return JsonData.buildFromReturnT(ReturnT.SUCCESS);
    }

    @BizLimit
    @PermissionLimit(limit = false)
    @PostMapping("/nextTriggerTime")
    public JsonData nextTriggerTime(@RequestBody NextTriggerTimeDto nextTriggerTimeDto) {
        String scheduleType = nextTriggerTimeDto.getScheduleType();
        String scheduleConf = nextTriggerTimeDto.getScheduleConf();
        XxlJobInfo paramXxlJobInfo = new XxlJobInfo();
        paramXxlJobInfo.setScheduleType(scheduleType);
        paramXxlJobInfo.setScheduleConf(scheduleConf);

        List<String> result = new ArrayList<>();
        try {
            Date lastTime = new Date();
            for (int i = 0; i < 5; i++) {
                lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
                if (lastTime != null) {
                    result.add(DateUtil.formatDateTime(lastTime));
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return JsonData.buildFromReturnT(new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type") + I18nUtil.getString("system_unvalid")) + e.getMessage()));
        }
        return JsonData.buildFromReturnT(new ReturnT<List<String>>(result));

    }
}
